package com.jyu.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jyu.mapper.ProductMapper;
import com.jyu.pojo.Product;
import com.jyu.pojo.ProductDetail;
import com.jyu.service.ProductDetailService;
import com.jyu.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.lang.model.util.ElementScanner6;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Scanner;

@Service
@Slf4j
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {

    @Autowired
    private ProductDetailService productDetailService;

    @Override
    @Transactional
    public void saveProduct() {
        log.info("正在进行商品录入操作...");
        Scanner scanner = new Scanner(System.in);

        String productId = inputProductId(scanner);

        String name = inputProductName(scanner);

        System.out.println("*****请输入商品价钱*****");
        String money = scanner.nextLine();
        float price = Float.parseFloat(money);
        System.out.println("*****请输入商品入库数量*****");
        String num = scanner.nextLine();
        int storageQuantity = 0;
        int status = 0;
        if (!num.equals("0")) {
            storageQuantity = Integer.parseInt(num);
            status = 1;
        }

        ProductDetail productDetail = ProductDetail.builder()
                .productId(productId)
                .price(price)
                .storageQuantity(storageQuantity)
                .storageDate(LocalDateTime.now())
                .status(status)
                .records(name + "在" + LocalDateTime.now() + "入库,并且存入数量" + storageQuantity)
                .build();

        Product product = Product.builder()
                .productId(productId)
                .productName(name)
                .stock(storageQuantity)
                .build();

        this.save(product);
        productDetailService.save(productDetail);
        System.out.println(name + "已成功入库！！！");

    }

    @Override
    public void listProduct() {
        log.info("正在进行查询所有商品操作...");
        List<Product> productList = this.list();
        if (productList.size() > 0 || productList != null) {
            System.out.println("============================================");
            System.out.println("商品名称" + "    " + "商品单号" + "    " + "商品剩余库存");
            for (Product product : productList) {
                System.out.println(product.getProductName() + "    " + product.getProductId() + "    " + product.getStock());
            }
            System.out.println("============================================");
            System.out.println("已查询完所有商品！！！");
        } else {
            System.out.println("该超市中不存在任何商品，请录入商品信息后重新查询！！！");
        }


    }

    @Override
    public void getByName() {
        log.info("正在进行查询商品明细操作（商品名字）...");
        Scanner scanner = new Scanner(System.in);
        System.out.println("*****请输入商品名称*****");
        String name = scanner.nextLine();
        LambdaQueryWrapper<Product> productLambdaQueryWrapper = new LambdaQueryWrapper<>();
        productLambdaQueryWrapper.eq(StringUtils.hasLength(name), Product::getProductName, name);
        Product product = this.getOne(productLambdaQueryWrapper);
        //先判断商品是否存在
        //存在才能查询商品明细
        if (product != null) {
            LambdaQueryWrapper<ProductDetail> productDetailLambdaQueryWrapper = new LambdaQueryWrapper<>();
            productDetailLambdaQueryWrapper.eq(StringUtils.hasLength(name), ProductDetail::getProductId, product.getProductId());
            ProductDetail productDetail = productDetailService.getOne(productDetailLambdaQueryWrapper);
            System.out.println("============================================");
            System.out.println("             以下是" + product.getProductName() + "信息明细      ");
            System.out.println("商品单号：" + product.getProductId());
            System.out.println("商品销售价钱：" + productDetail.getPrice());
            System.out.println("商品入库时间：" + productDetail.getStorageDate());
            System.out.println("商品入库数量：" + productDetail.getStorageQuantity());
            System.out.println("商品出库数量：" + (productDetail.getStorageQuantity() - product.getStock()));
            System.out.println("商品剩余库存数量：" + product.getStock());
            System.out.println("============================================");
            System.out.println(product.getProductName() + "信息明细查询完毕...");
        } else {
            System.out.println(name + "不存在！！！请重新查询！！！");
        }
    }

    @Override
    public void getByProductId() {
        log.info("正在进行查询商品明细操作（商品单号）...");
        Scanner scanner = new Scanner(System.in);
        System.out.println("*****请输入商品单号*****");
        String productId = scanner.nextLine();
        LambdaQueryWrapper<Product> productLambdaQueryWrapper = new LambdaQueryWrapper<>();
        productLambdaQueryWrapper.eq(StringUtils.hasLength(productId), Product::getProductId, productId);
        Product product = this.getOne(productLambdaQueryWrapper);
        //先判断商品是否存在
        //存在才能查询商品明细
        if (product != null) {
            LambdaQueryWrapper<ProductDetail> productDetailLambdaQueryWrapper = new LambdaQueryWrapper<>();
            productDetailLambdaQueryWrapper.eq(StringUtils.hasLength(productId), ProductDetail::getProductId, product.getProductId());
            ProductDetail productDetail = productDetailService.getOne(productDetailLambdaQueryWrapper);
            System.out.println("============================================");
            System.out.println("             以下是" + "单号为" + productId + "信息明细      ");
            System.out.println("商品单号：" + product.getProductId());
            System.out.println("商品销售价钱：" + productDetail.getPrice());
            System.out.println("商品入库时间：" + productDetail.getStorageDate());
            System.out.println("商品入库数量：" + productDetail.getStorageQuantity());
            System.out.println("商品出库数量：" + (productDetail.getStorageQuantity() - product.getStock()));
            System.out.println("商品剩余库存数量：" + product.getStock());
            System.out.println("============================================");
            System.out.println("单号为" + productId + "信息明细查询完毕...");
        } else {
            System.out.println("单号为" + productId + "不存在！！！请重新查询！！！");
        }
    }

    @Override
    public void countOnSale() {
        log.info("正在进行统计超市剩余商品种类数量...");
        LambdaQueryWrapper<ProductDetail> productLambdaQueryWrapper = new LambdaQueryWrapper<>();
        productLambdaQueryWrapper.eq(ProductDetail::getStatus, 1);
        long count = productDetailService.count(productLambdaQueryWrapper);
        System.out.println("超市商品种类有" + count + "种");
        System.out.println("统计结束...");
    }


    @Override
    @Transactional
    public void removeAll() {
        log.info("正在进行清空所有超市商品操作...");
        List<Product> productList = this.list();
        if (productList.size() > 0 && productList != null) {
            for (Product product : productList) {
                ProductDetail newProductDetail = new ProductDetail();
                LambdaQueryWrapper<ProductDetail> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(ProductDetail::getProductId, product.getProductId());
                ProductDetail productDetail = productDetailService.getOne(queryWrapper);

                //更新原本的商品信息明细
                LambdaUpdateWrapper<ProductDetail> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                lambdaUpdateWrapper.eq(ProductDetail::getProductId, productDetail.getProductId())
                        .eq(ProductDetail::getStatus, 1);
                productDetail.setStatus(0);
                productDetailService.update(productDetail, lambdaUpdateWrapper);

                //添加新的商品信息明细
                BeanUtils.copyProperties(productDetail, newProductDetail, "records", "id");
                newProductDetail.setRecords(product.getProductName() + "在" + LocalDateTime.now() + "被清空");
                productDetailService.save(newProductDetail);
                this.removeById(product.getId());
                System.out.println("超市商品全部清空完成...");
            }
        } else {
            System.out.println("超市商品已为空！！！");
        }
    }

    @Override
    @Transactional
    public void removeByProductName() {
        log.info("正在进行清空某件超市商品操作（商品名称）...");
        Scanner scanner = new Scanner(System.in);
        System.out.println("*****请输入待删除商品名称*****");
        String productName = scanner.nextLine();
        LambdaQueryWrapper<Product> productLambdaQueryWrapper = new LambdaQueryWrapper<>();
        productLambdaQueryWrapper.eq(StringUtils.hasLength(productName), Product::getProductName, productName);
        Product product = this.getOne(productLambdaQueryWrapper);
        if (product != null) {
            ProductDetail newProductDetail = new ProductDetail();
            LambdaQueryWrapper<ProductDetail> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ProductDetail::getProductId, product.getProductId());
            ProductDetail productDetail = productDetailService.getOne(queryWrapper);

            //更新原本的商品信息明细
            LambdaUpdateWrapper<ProductDetail> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(ProductDetail::getProductId, productDetail.getProductId())
                    .eq(ProductDetail::getStatus, 1);
            productDetail.setStatus(0);
            productDetailService.update(productDetail, lambdaUpdateWrapper);

            //添加新的商品信息明细
            BeanUtils.copyProperties(productDetail, newProductDetail, "records", "id");
            newProductDetail.setRecords(product.getProductName() + "在" + LocalDateTime.now() + "被清空");
            productDetailService.save(newProductDetail);

            this.removeById(product.getId());
            System.out.println(productName + "商品删除完成...");

        } else {
            System.out.println(productName + "商品不存在！！！");
        }
    }

    @Override
    @Transactional
    public void removeByProductId() {
        log.info("正在进行清空某件超市商品操作（商品单号）...");
        Scanner scanner = new Scanner(System.in);
        System.out.println("*****请输入待删除商品单号*****");
        String productId = scanner.nextLine();
        LambdaQueryWrapper<Product> productLambdaQueryWrapper = new LambdaQueryWrapper<>();
        productLambdaQueryWrapper.eq(StringUtils.hasLength(productId), Product::getProductId, productId);
        Product product = this.getOne(productLambdaQueryWrapper);
        if (product != null) {
            ProductDetail newProductDetail = new ProductDetail();
            LambdaQueryWrapper<ProductDetail> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ProductDetail::getProductId, product.getProductId());
            ProductDetail productDetail = productDetailService.getOne(queryWrapper);

            //更新原本的商品信息明细
            LambdaUpdateWrapper<ProductDetail> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(ProductDetail::getProductId, productDetail.getProductId())
                    .eq(ProductDetail::getStatus, 1);
            productDetail.setStatus(0);
            productDetailService.update(productDetail, lambdaUpdateWrapper);

            //添加新的商品信息明细
            BeanUtils.copyProperties(productDetail, newProductDetail, "records", "id");
            newProductDetail.setRecords(product.getProductName() + "在" + LocalDateTime.now() + "被清空");
            productDetailService.save(newProductDetail);

            this.removeById(product.getId());
            System.out.println("单号为" + productId + "商品删除完成...");
        } else {
            System.out.println("单号为" + productId + "商品不存在！！！");
        }
    }

    @Override
    @Transactional
    public void updateByProductId() {
        log.info("正在进行修改商品操作（商品单号）...");
        Scanner scanner = new Scanner(System.in);
        System.out.println("*****请输入待修改商品单号*****");
        String productId = scanner.nextLine();
        LambdaQueryWrapper<Product> productLambdaQueryWrapper = new LambdaQueryWrapper<>();
        productLambdaQueryWrapper.eq(StringUtils.hasLength(productId), Product::getProductId, productId);
        Product product = this.getOne(productLambdaQueryWrapper);

        if (product != null) {

            String name = inputProductName(scanner);

            System.out.println("*****请输入商品价钱*****");
            String money = scanner.nextLine();
            float newPrice = Float.parseFloat(money);

            System.out.println("*****请输入商品入库数量*****");
            String newNum = scanner.nextLine();
            int storageQuantity = Integer.parseInt(newNum);

            int status = 0;
            if (!newNum.equals("0")) {
                status = 1;
            }

            //更新原本的商品信息明细
            LambdaQueryWrapper<ProductDetail> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ProductDetail::getProductId, productId)
                    .eq(ProductDetail::getStatus, 1);
            ProductDetail productDetail = productDetailService.getOne(queryWrapper);
            LambdaUpdateWrapper<ProductDetail> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(ProductDetail::getProductId, product.getProductId())
                    .eq(ProductDetail::getStatus, 1);
            productDetail.setStatus(0);
            productDetailService.update(productDetail, lambdaUpdateWrapper);

            //添加新的商品信息明细
            ProductDetail newProductDetail = ProductDetail.builder()
                    .productId(productId)
                    .price(newPrice)
                    .storageQuantity(storageQuantity)
                    .status(status)
                    .storageDate(LocalDateTime.now())
                    .records("单号为" + productId + "在" + LocalDateTime.now() + "修改")
                    .build();
            productDetailService.save(newProductDetail);

            //修改新的商品信息
            Product newProduct = Product.builder()
                    .productName(name)
                    .stock(storageQuantity)
                    .build();
            LambdaUpdateWrapper<Product> productLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            productLambdaUpdateWrapper.eq(Product::getProductId, productId);
            this.update(newProduct, productLambdaUpdateWrapper);

            System.out.println("单号为" + productId + "商品修改完成...");
        } else {
            System.out.println("单号为" + productId + "商品不存在！！！");
        }
    }

    @Transactional
    @Override
    public void updateByProductName() {
        log.info("正在进行修改商品操作（商品名称）...");
        Scanner scanner = new Scanner(System.in);
        System.out.println("*****请输入待修改商品名称*****");
        String productName = scanner.nextLine();
        LambdaQueryWrapper<Product> productLambdaQueryWrapper = new LambdaQueryWrapper<>();
        productLambdaQueryWrapper.eq(StringUtils.hasLength(productName), Product::getProductName, productName);
        Product product = this.getOne(productLambdaQueryWrapper);

        if (product != null) {

            String productId = inputProductId(scanner);

            System.out.println("*****请输入商品价钱*****");
            String money = scanner.nextLine();
            float newPrice = Float.parseFloat(money);

            System.out.println("*****请输入商品入库数量*****");
            String newNum = scanner.nextLine();
            int storageQuantity = Integer.parseInt(newNum);

            int status = 0;
            if (!newNum.equals("0")) {
                status = 1;
            }

            //更新原本的商品信息明细
            LambdaQueryWrapper<ProductDetail> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ProductDetail::getProductId, product.getProductId())
                    .eq(ProductDetail::getStatus, 1);
            ProductDetail productDetail = productDetailService.getOne(queryWrapper);
            LambdaUpdateWrapper<ProductDetail> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(ProductDetail::getProductId, product.getProductId())
                    .eq(ProductDetail::getStatus, 1);
            productDetail.setStatus(0);
            productDetailService.update(productDetail, lambdaUpdateWrapper);

            //添加新的商品信息明细
            ProductDetail newProductDetail = ProductDetail.builder()
                    .productId(productId)
                    .price(newPrice)
                    .storageQuantity(storageQuantity)
                    .status(status)
                    .storageDate(LocalDateTime.now())
                    .records("单号为" + product.getProductId() + "在" + LocalDateTime.now() + "修改")
                    .build();
            productDetailService.save(newProductDetail);

            //修改新的商品信息
            Product newProduct = Product.builder()
                    .productId(productId)
                    .stock(storageQuantity)
                    .build();

            LambdaUpdateWrapper<Product> productLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            productLambdaUpdateWrapper.eq(Product::getProductName, productName);
            this.update(newProduct, productLambdaUpdateWrapper);

            System.out.println("商品名称为" + productName + "修改完成...");
        } else {
            System.out.println("商品名称为" + productName + "不存在！！！");
        }
    }

    @Override
    public void productOutboundById() {
        log.info("正在根据商品单号出库...");
        Scanner scanner = new Scanner(System.in);
        System.out.println("*****请输入要出库商品的单号*****");
        String productId = scanner.nextLine();

        LambdaQueryWrapper<Product> productLambdaQueryWrapper = new LambdaQueryWrapper<>();
        productLambdaQueryWrapper.eq(StringUtils.hasLength(productId), Product::getProductId, productId);
        Product product = this.getOne(productLambdaQueryWrapper);
        if (product != null) {
            //修改商品明细
            LambdaQueryWrapper<ProductDetail> productDetailLambdaQueryWrapper = new LambdaQueryWrapper<>();
            productDetailLambdaQueryWrapper.eq(ProductDetail::getProductId, product.getProductId())
                    .eq(ProductDetail::getStatus, 1);
            ProductDetail productDetail = productDetailService.getOne(productDetailLambdaQueryWrapper);
            int outboundQuantity = 0;
            while (true) {
                System.out.println("*****请输入要出库商品的数量*****");
                String num = scanner.nextLine();
                outboundQuantity = Integer.parseInt(num);
                if (outboundQuantity <= product.getStock()) {
                    break;
                } else {
                    System.out.println("出库数量大于库存数量，请重新输入！！！");
                    continue;
                }
            }
            ProductDetail updateProductDetail = ProductDetail.builder()
                    .outboundDate(LocalDateTime.now())
                    .outboundQuantity(outboundQuantity)
                    .records(productDetail.getRecords() + "~~该" + product.getProductName() + "在" + LocalDateTime.now() + "出库了" + outboundQuantity)
                    .build();
            LambdaUpdateWrapper<ProductDetail> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(ProductDetail::getProductId, product.getProductId())
                    .eq(ProductDetail::getStatus, 1);
            productDetailService.update(updateProductDetail, lambdaUpdateWrapper);

            //修改商品库存数量
            Product updateProduct = Product.builder()
                    .stock(product.getStock() - outboundQuantity)
                    .build();
            LambdaUpdateWrapper<Product> productLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            productLambdaUpdateWrapper.eq(Product::getProductId, productId);
            this.update(updateProduct, productLambdaUpdateWrapper);
            System.out.println(productId + "出库完成！！！");
        } else {
            System.out.println("单号为" + productId + "商品不存在！！！");
        }

    }

    @Override
    public void productOutboundByName() {
        log.info("正在根据商品名称出库...");
        Scanner scanner = new Scanner(System.in);
        System.out.println("*****请输入要出库商品的名称*****");
        String productName = scanner.nextLine();

        LambdaQueryWrapper<Product> productLambdaQueryWrapper = new LambdaQueryWrapper<>();
        productLambdaQueryWrapper.eq(StringUtils.hasLength(productName), Product::getProductName, productName);
        Product product = this.getOne(productLambdaQueryWrapper);
        if (product != null) {
            //修改商品明细
            LambdaQueryWrapper<ProductDetail> productDetailLambdaQueryWrapper = new LambdaQueryWrapper<>();
            productDetailLambdaQueryWrapper.eq(ProductDetail::getProductId, product.getProductId())
                    .eq(ProductDetail::getStatus, 1);
            ProductDetail productDetail = productDetailService.getOne(productDetailLambdaQueryWrapper);
            int outboundQuantity = 0;
            while (true) {
                System.out.println("*****请输入要出库商品的数量*****");
                String num = scanner.nextLine();
                outboundQuantity = Integer.parseInt(num);
                if (outboundQuantity <= product.getStock()) {
                    break;
                } else {
                    System.out.println("出库数量大于库存数量，请重新输入！！！");
                    continue;
                }
            }
            ProductDetail updateProductDetail = ProductDetail.builder()
                    .outboundDate(LocalDateTime.now())
                    .outboundQuantity(outboundQuantity)
                    .records(productDetail.getRecords() + "~~该" + productName + "在" + LocalDateTime.now() + "出库了" + outboundQuantity)
                    .build();
            LambdaUpdateWrapper<ProductDetail> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(ProductDetail::getProductId, product.getProductId())
                    .eq(ProductDetail::getStatus, 1);
            productDetailService.update(updateProductDetail, lambdaUpdateWrapper);

            //修改商品库存数量
            Product updateProduct = Product.builder()
                    .stock(product.getStock() - outboundQuantity)
                    .build();
            LambdaUpdateWrapper<Product> productLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            productLambdaUpdateWrapper.eq(Product::getProductName, productName);
            this.update(updateProduct, productLambdaUpdateWrapper);
            System.out.println(productName + "出库完成！！！");
        } else {
            System.out.println("名称为" + productName + "商品不存在！！！");
        }

    }


    private String inputProductId(Scanner scanner) {
        while (true) {
            System.out.println("*****请输入商品单号*****");
            String newProductId = scanner.nextLine();
            LambdaQueryWrapper<Product> productLambdaQueryWrapper1 = new LambdaQueryWrapper<>();
            productLambdaQueryWrapper1.eq(StringUtils.hasLength(newProductId), Product::getProductId, newProductId);
            Product checkProduct = this.getOne(productLambdaQueryWrapper1);
            if (checkProduct != null) {
                System.out.println("该商品单号已存在，请重新输入！！");
            } else if (newProductId.length() == 0) {
                System.out.println("该商品单号不合法，请重新输入！！!");
                continue;
            } else
                return newProductId;
        }
    }

    private String inputProductName(Scanner scanner) {
        while (true) {
            System.out.println("*****请输入商品名称*****");
            String newName = scanner.nextLine();
            LambdaQueryWrapper<Product> productLambdaQueryWrapper1 = new LambdaQueryWrapper<>();
            productLambdaQueryWrapper1.eq(StringUtils.hasLength(newName), Product::getProductName, newName);
            Product checkProduct = this.getOne(productLambdaQueryWrapper1);
            if (checkProduct != null) {
                System.out.println("该商品名称已存在，请重新输入！！!");
            } else if (newName.length() == 0) {
                System.out.println("该商品名称不合法，请重新输入！！!");
                continue;
            } else
                return newName;
        }
    }
}
